#include <iostream>
#include <cstdlib>
#include <string>

#include "volume.local.h"
#include "volume.merger.h"
#include "entry.h"

using namespace jolfs;

void print_indent( unsigned int indent )
{
  for ( unsigned int i=0; i<indent; ++i )
    std::cout << "    ";
}

void print_entry( const Entry* entry, unsigned int indent=0 )
{
  // sanity check
  if ( entry == 0 )
  {
    std::cout << "0" << std::endl;
    return;
  }
  
  std::string type;
  switch( entry->getType() )
  {
    case Entry::DIRECTORY:
      type = "d";
      break;
    case Entry::FILE:
      type = "-";
      break;
    default:
      type = "-";
      break;
  }

  std::string mode;
  Entry::mode_t m = entry->getMode();

  mode.append( UMODE(1,0,0) & m ? "r" : "-" );
  mode.append( UMODE(0,1,0) & m ? "w" : "-" );
  mode.append( UMODE(0,0,1) & m ? "x" : "-" );
  
  mode.append( GMODE(1,0,0) & m ? "r" : "-" );
  mode.append( GMODE(0,1,0) & m ? "w" : "-" );
  mode.append( GMODE(0,0,1) & m ? "x" : "-" );
  
  mode.append( OMODE(1,0,0) & m ? "r" : "-" );
  mode.append( OMODE(0,1,0) & m ? "w" : "-" );
  mode.append( OMODE(0,0,1) & m ? "x" : "-" );
  
  print_indent(indent);
  std::cout << type << mode << " " << entry->getSize() << " " << entry->getName() << std::endl;;
}

void print_entries( const EntryList& list, unsigned int indent=0 )
{
  EntryList::const_iterator it = list.begin();
  for (; it!=list.end(); ++it )
  {
    print_entry( *it, indent );
    if ( (*it)->getType()==Entry::DIRECTORY )
      print_entries( (*it)->getChildren(), indent+1 );
  }
}

int main( int argc, char** argv )
{
  LocalVolume  volume_a( "a", "/tmp/jolfs/a" );
  LocalVolume  volume_b( "b", "/tmp/jolfs/b" );
  MergerVolume volume_ab( "ab" );
  
  volume_ab.addMergedVolume( &volume_a );
  volume_ab.addMergedVolume( &volume_b );
  std::cout << "Volume ab/" << std::endl;
  print_entries( volume_ab.getEntries(), 1 );
  
  std::string path0 = "/";
  std::string path1 = "/b/b1";
  std::string path2 = "a/a4/";
  std::string path3 = "/a/a4/a42";
  std::string path4 = "/none";
  std::string path5 = "/a4/none/";
 
  std::cout << "Entry for path " << path0 << ": ";
  print_entry( volume_ab.getEntry(path0) );

  std::cout << "Entry for path " << path1 << ": ";
  print_entry( volume_ab.getEntry(path1) );
  
  std::cout << "Entry for path " << path2 << ": ";
  print_entry( volume_ab.getEntry(path2) );
  
  std::cout << "Entry for path " << path3 << ": ";
  print_entry( volume_ab.getEntry(path3) );
  
  std::cout << "Entry for path " << path4 << ": ";
  print_entry( volume_ab.getEntry(path4) );
  
  std::cout << "Entry for path " << path5 << ": ";
  print_entry( volume_ab.getEntry(path5) );
 
  return EXIT_SUCCESS;
}